home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / comm / tcp / dct16_src.lzh / dctelnet-1.6 / DCTelnet.c < prev    next >
C/C++ Source or Header  |  2000-09-21  |  54KB  |  2,423 lines

  1. /* ====================================================================== */
  2. /* ============================= DC TELNET ============================== */
  3. /* ====================================================================== */
  4.  
  5. static const char __version[]="\0$VER: DCTelnet 1.5 ("__DATE__")";
  6.  
  7. #define __USE_SYSBASE
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <proto/exec.h>
  12. #include <proto/dos.h>
  13. #include <proto/intuition.h>
  14. #include <proto/graphics.h>
  15. #include <proto/gadtools.h>
  16. #include <proto/diskfont.h>
  17. #include <proto/utility.h>
  18. #include <proto/icon.h>
  19. #include <proto/wb.h>
  20. #include <proto/keymap.h>
  21. #include <intuition/screens.h>
  22. #include <intuition/gadgetclass.h>
  23. #include <exec/memory.h>
  24. #include <exec/execbase.h>
  25. #include <libraries/reqtools.h>
  26. #include <proto/reqtools.h>
  27. #include <sys/errno.h>
  28. #include <netdb.h>
  29. #include <proto/socket.h>
  30. #include <xem.h>
  31. #include <xem_proto.h>
  32.  
  33.  
  34. struct NewMenu mynewmenu[] =
  35.     {
  36.         { NM_TITLE, "DC Telnet",     0 , 0, 0, 0,},
  37.         {  NM_ITEM, "About",        "A", 0, 0, 0,},
  38.         {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, 0,},
  39.         {  NM_ITEM, "Scroll Back",    "X", 0, 0, 0,},
  40.         {  NM_ITEM, "Iconify",         "&", 0, 0, 0,},
  41.         {  NM_ITEM, "Speed Test",    "Y", 0, 0, 0,},
  42.         {  NM_ITEM, "Finger",        "@", 0, 0, 0,},
  43.         {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, 0,},
  44.         {  NM_ITEM, "Quit",        "Q", 0, 0, 0,},
  45.  
  46.         { NM_TITLE, "Transfer",         0 , 0, 0, 0,},
  47.         {  NM_ITEM, "Upload",           "U", 0, 0, 0,},
  48.         {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, 0,},
  49.         {  NM_ITEM, "Download",        "D", 0, 0, 0,},
  50.         {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, 0,},
  51.         {  NM_ITEM, "ASCII Send",    "%", 0, 0, 0,},
  52.  
  53.         { NM_TITLE, "Connection",     0 , 0, 0, 0,},
  54.         {  NM_ITEM, "Connect",        "M", 0, 0, 0,},
  55.         {  NM_ITEM, "Connect Thread",    "G", 0, 0, 0,},
  56.         {  NM_ITEM, "Disconnect",    "H", 0, 0, 0,},
  57.         {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, 0,},
  58.         {  NM_ITEM, "Address Book",    "B", 0, 0, 0,},
  59.         {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, 0,},
  60.         {  NM_ITEM, "Information",    "^", 0, 0, 0,},
  61.  
  62.         { NM_TITLE, "Options",          0 , 0, 0, 0,},        // 23
  63.         {  NM_ITEM, "Use Workbench",    "W", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  64.         {  NM_ITEM, "Disable LEDs",    "I", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  65.         {  NM_ITEM, "Hide TitleBar",    "R", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  66.         {  NM_ITEM, "CRLF Correction",    "L", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  67.         {  NM_ITEM, "BS/DEL Swap",    "/", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  68.         {  NM_ITEM, "Disable Scroll-B",    "E", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  69.         {  NM_ITEM, "Strip Colour",    "J", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  70.         {  NM_ITEM, "Simple Telnet",    "1", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  71.         {  NM_ITEM, "Packet Window",    "2", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  72.         {  NM_ITEM, "Use XEM Library",    "3", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  73.         {  NM_ITEM, "Tool Window",    "4", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  74.         {  NM_ITEM, "Return = CR + LF",    "5", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  75.         {  NM_ITEM, "Local Echoback",    "6", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  76.         {  NM_ITEM, "Raw Connection",    "7", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  77.         {  NM_ITEM, "Jump Scroll",    "8", HIGHCOMP|CHECKIT|MENUTOGGLE, 0, 0,},
  78.  
  79.         { NM_TITLE, "Settings",         0 , 0, 0, 0,},
  80.         {  NM_ITEM, "Screen Mode..",    "S", 0, 0, 0,},
  81.         {  NM_ITEM, "Screen Font..",    "F", 0, 0, 0,},
  82.         {  NM_ITEM, "Screen Palette..",    "-", 0, 0, 0,},
  83.         {  NM_ITEM, "Download Path..",    "O", 0, 0, 0,},
  84.         {  NM_ITEM, "Transfer Protocol..","T", 0, 0, 0,},
  85.         {  NM_ITEM, "Protocol Init..",    "*", 0, 0, 0,},
  86.         {  NM_ITEM, "Function Keys..",    "K", 0, 0, 0,},
  87.         {  NM_ITEM, "XEM Library..",    "#", 0, 0, 0,},
  88.         {  NM_ITEM, "Telnet Display ID..","9", 0, 0, 0,},
  89.         {  NM_ITEM, "ScrollBack Lines..","0", 0, 0, 0,},
  90.     {  NM_ITEM, "Snapshot Windows",    "$", 0, 0, 0,},
  91.  
  92.         { NM_TITLE, "Login",         0 , 0, 0, 0,},
  93.         {  NM_ITEM, "Send Username",    "N", 0, 0, 0,},
  94.         {  NM_ITEM, "Send Password",    "P", 0, 0, 0,},
  95.  
  96.         {   NM_END, NULL,         0 , 0, 0, 0,},
  97.     };
  98.  
  99. UWORD Connect_To_Server(char *servername, UWORD port);
  100. void ConWrite(char *data, long len);
  101. void LocalPrint(char *data);
  102. void GetWindowMsg(struct Window *wwin);
  103. void CloseDisplay(char);
  104. char OpenDisplay(char);
  105. void OpenIcon(void);
  106. void CloseIcon(void);
  107. void LEDs(void);
  108.  
  109. extern void CloseScrollBack(void);
  110. extern void OpenScrollBack(UWORD sel);
  111. extern void FunctionKeys(void);
  112. extern void Upload(char *library);
  113. extern void Download(char *library);
  114. extern void AddressBook(void);
  115. extern long mytime(void);
  116. extern void RefreshListView(UWORD top);
  117. extern void OpenToolWindow(char setmenus);
  118. extern void CloseToolWindow(void);
  119. extern void CheckDimensions(struct NewWindow *newwin);
  120.  
  121. extern LONG __saveds __asm xpr_swrite(register __a0 UBYTE *buffer, register __d0 LONG size);
  122. extern LONG __saveds __asm xpr_sread(register __a0 UBYTE *buffer, register __d0 ULONG size, register __d1 ULONG timeout);
  123. extern LONG __saveds __asm xpr_sflush(void);
  124. extern LONG __asm xpr_gets(register __a0 STRPTR Prompt,register __a1 STRPTR Buffer);
  125.  
  126. extern APTR Scroller;
  127. extern struct ExecBase *SysBase;
  128. struct ReqToolsBase *ReqToolsBase;
  129. struct IntuitionBase *IntuitionBase;
  130. struct GfxBase *GfxBase;
  131. struct Library *KeymapBase, *XEmulatorBase, *GadToolsBase, *SocketBase;
  132. struct Library *DiskfontBase, *IconBase, *WorkbenchBase, *UtilityBase;
  133. struct Window *win, *pwin, *sbwin, *twin;
  134. struct List *slist;
  135. struct Screen *scr;
  136. struct DrawInfo *DrawInfo;
  137. struct Gadget window_back;
  138. struct NewGadget ng;
  139. struct TextAttr fontattr;
  140. struct TextFont *ansifont;
  141. struct IOStdReq writeio;
  142. struct MsgPort *WriteConPort;
  143. struct Menu *menuStrip;
  144. struct DiskObject *dobj;
  145. struct MsgPort *iconport;
  146. struct AppIcon *dcicon;
  147. struct hostent *HostAddr;
  148. struct sockaddr_in INetSocketAddr;
  149. struct XEM_IO xemio;
  150. struct NewWindow nwin;
  151.  
  152. #define BUFSIZE 250
  153. UBYTE strBuffer[BUFSIZE+2];
  154. struct StringInfo strInfo;
  155. struct Gadget strGad;
  156.  
  157. enum    {    GAD_SCROLLER,
  158.         GAD_UP,
  159.         GAD_DOWN
  160.     };
  161.  
  162. struct PrefsStruct
  163. {
  164.     ULONG    DisplayID;
  165.         UWORD    DisplayWidth,
  166.         DisplayHeight,
  167.         DisplayDepth,
  168.         fontsize;
  169.     char    fontname[32],
  170.         downloadpath[52],
  171.         xferlibrary[52],
  172.         xferinit[52];
  173.     UWORD    color[16];
  174.     ULONG    flags;    /* --->    BIT 0 = Hide Title Bar */
  175.     UWORD    win_left,    /* BIT 1 = CRLF Correction */
  176.         win_top,    /* BIT 2 = Hide LEDS */
  177.         win_width,    /* BIT 3 = Use Workbench */
  178.         win_height,    /* BIT 4 = BS/DEL Swap */
  179.         sb_left,    /* BIT 5 = Disable Logging */
  180.         sb_top,        /* BIT 6 = Strip Colour */
  181.         sb_width,    /* BIT 7 = Simple Negotiation */
  182.         sb_height;    /* BIT 8 = Packet Window */
  183.     char    uploadpath[52],    /* BIT 9 = Display Driver */
  184.         displaydriver[32];/*IT 10 = Tool Window */
  185.     ULONG    sb_lines;    /* BIT 11 = Return = CR&LF */
  186.     char    displayidstr[32];/* IT 12 = Local Echoback */
  187.     UWORD    twin_left,    /* BIT 13 = Raw Connection */
  188.         twin_top;    /* BIT 14 = Jump Scroll */
  189. } prefs;
  190.  
  191. ULONG tags[5];
  192. BPTR fh;
  193. long jj, lines;
  194. long contime, sok, bytes, sent;
  195. void *vi;
  196. char username[42], password[42];
  197. unsigned char buf[2048], conbuf[16], scrollbuf[402], keys[1520];
  198. char server[64];
  199. ULONG lasttop;        // last topline of scrollback
  200. UWORD cport = 23;    // current tcp port
  201. UWORD WinTop;        // WinTop topEdge (titlebar height)
  202. UBYTE done;        // program finished
  203. UBYTE connected;    // tcp connected
  204. UBYTE passall;        // passall telnet negotiation
  205. UBYTE passflag;        // already sent 8bit info
  206. UBYTE restartflag;    // prefs changed, restart
  207. UBYTE reopenscreen;    // flag
  208. UBYTE wb;        // running in wb
  209. UBYTE icon;        // iconified
  210. UBYTE doicon;        // must iconify
  211. UBYTE unicon;        // must uniconify
  212. UBYTE drivertype;    // drivertype 0 - normal    1 - xem library
  213. UBYTE finger;        // finger? BOOLEAN
  214.  
  215. UWORD colorpens[]  = { 1,4,1,1,6,4,1,0,5,4,1,6,65535 };
  216. UWORD color[] = { 0x0000, 0x0DDD, 0x00D0, 0x0DD0, 0x000D, 0x0D0D, 0x00DD, 0x0D00,
  217.           0x0555, 0x0FFF, 0x00F0, 0x0FF0, 0x000F, 0x0F0F, 0x00FF, 0x0F00, 65535 };
  218. /*                 black,    white,  green, yellow, blue, purple, aqua,   red */
  219.  
  220. char prefsfile[] = "PROGDIR:DCTelnet.Prefs";
  221. char bookfile[]  = "PROGDIR:DCTelnet.Book";
  222. char keysfile[]  = "PROGDIR:DCTelnet.Keys";
  223.  
  224.  
  225. void mysprintf(char *Buffer, char *ctl, ...)
  226. {
  227.     RawDoFmt(ctl, (long *)(&ctl + 1), (void (*))"\x16\xc0\x4e\x75", Buffer);
  228. }
  229.  
  230. void LocalFmt(char *ctl, ...)
  231. {
  232.     RawDoFmt(ctl, (long *)(&ctl + 1), (void (*))"\x16\xc0\x4e\x75", buf);
  233.     ConWrite(buf, strlen(buf));
  234. }
  235.  
  236. void TextFmt(struct RastPort *rP, char *ctl, ...)
  237. {
  238.     RawDoFmt(ctl, (long *)(&ctl + 1), (void (*))"\x16\xc0\x4e\x75", buf);
  239.     Text(rP, buf, strlen(buf));
  240. }
  241.  
  242. long TCPSend(char *buf, long len)
  243. {
  244.     if(send(sok, buf, len, 0) < 0) return -1;
  245.     sent += len;
  246.     return len;
  247. }
  248.  
  249. void WindowSub(void (*Sub)(void))
  250. {
  251.     if(sbwin) rtSetWaitPointer(sbwin);
  252.     if(twin) rtSetWaitPointer(twin);
  253.     rtSetWaitPointer(win);
  254.     Sub();
  255.     if(sbwin) ClearPointer(sbwin);
  256.     if(twin) ClearPointer(twin);
  257.     ClearPointer(win);
  258.     LEDs();
  259. }
  260.  
  261. void SimpleReq(char *str)
  262. {
  263.     rtEZRequestA(str, "OK", NULL, NULL, (struct TagItem *)&tags);
  264.     LEDs();
  265. }
  266.  
  267. void DisConnect(char remote, char quiet)
  268. {
  269.     if(connected)
  270.     {
  271.         if(!quiet && !icon)
  272.         {
  273.             register long spent;
  274.             if(remote)
  275.                 LocalPrint("›m\r\nConnection closed by foreign host");
  276.             else
  277.                 LocalPrint("›m\r\nConnection closed");
  278.             spent = mytime() - contime;
  279.             LocalFmt(". %02ld:%02ld:%02ld spent online.\r\n", spent/3600, (spent/60)%60, spent%60);
  280.         }
  281.         shutdown(sok, 2);
  282.         CloseSocket(sok);
  283.  
  284.         connected = FALSE;
  285.         passall = FALSE;
  286.         passflag = FALSE;
  287.         bytes = 0;
  288.         sent = 0;
  289.  
  290.         if(finger)
  291.         {
  292.             finger = FALSE;
  293.             OnMenu(win, FULLMENUNUM(3, -1, 0));
  294.         }
  295.  
  296.         LEDs();
  297.     }
  298. }
  299.  
  300. void SavePrefs(void)
  301. {
  302.     fh = Open(prefsfile, MODE_NEWFILE);
  303.     if(fh)
  304.     {
  305.         Write(fh, &prefs, sizeof(struct PrefsStruct));
  306.         Close(fh);
  307.     }
  308. }
  309.  
  310. char ChooseScreen(char firsttime)
  311. {
  312.     struct rtScreenModeRequester *scrmodereq;
  313.  
  314.     if(scrmodereq = rtAllocRequestA (RT_SCREENMODEREQ, NULL))
  315.     {
  316.         if(firsttime)
  317.         {
  318.             scrmodereq->DisplayID = HIRES_KEY;//PAL_MONITOR_ID
  319.             scrmodereq->DisplayDepth = 4;
  320.             scrmodereq->DisplayWidth = 640;
  321.             scrmodereq->DisplayHeight = 256;
  322.         } else {
  323.             //rtChangeReqAttr(scrmodereq, RTSC_ModeFromScreen, scr, TAG_END);
  324.             scrmodereq->DisplayID = prefs.DisplayID;
  325.             scrmodereq->DisplayWidth = prefs.DisplayWidth;
  326.             scrmodereq->DisplayHeight = prefs.DisplayHeight;
  327.             scrmodereq->DisplayDepth = prefs.DisplayDepth;
  328.         }
  329.  
  330.         if (rtScreenModeRequest (scrmodereq, "Screen Mode..",
  331.             RT_Window,    win,
  332.             RTSC_Flags,    SCREQF_DEPTHGAD|SCREQF_SIZEGADS|SCREQF_GUIMODES,
  333.             RTSC_MaxDepth,    4,
  334.             TAG_END))
  335.         {
  336.             prefs.DisplayID = scrmodereq->DisplayID;
  337.             prefs.DisplayWidth = scrmodereq->DisplayWidth;
  338.             prefs.DisplayHeight = scrmodereq->DisplayHeight;
  339.             prefs.DisplayDepth = scrmodereq->DisplayDepth;
  340.             rtFreeRequest (scrmodereq);
  341.             return(TRUE);
  342.         }
  343.         rtFreeRequest (scrmodereq);
  344.     }
  345.     return(FALSE);
  346. }
  347.  
  348. char FileReq(char *dir, char *pat, char *file, char *title, char dodir, ULONG flags)
  349. {
  350.     struct rtFileRequester *filereq;
  351.     char fbuf[128];
  352.  
  353.     if (filereq = rtAllocRequestA (RT_FILEREQ, NULL))
  354.     {
  355.         strcpy(fbuf, file);
  356.         rtChangeReqAttr(filereq,
  357.             RTFI_MatchPat,    pat,
  358.             RTFI_Dir,    dir,
  359.             TAG_END);
  360.         if (rtFileRequest (filereq, fbuf, title,
  361.             RT_Window,    win,
  362.             RT_LeftOffset,    20,
  363.             RT_TopOffset,    0,
  364.             RTFI_Height,    600,
  365.             RTFI_Flags,    flags,
  366.             TAG_END))
  367.         {
  368.             strcpy(file, fbuf);
  369.             if(dodir)
  370.             {
  371.                 WORD l;
  372.                 strcpy(dir, filereq->Dir);
  373.                 l = strlen(dir) - 1;
  374.                 if(l!=-1 && dir[l] != '/' && dir[l] != ':')
  375.                 {
  376.                     l++;
  377.                     dir[l] = '/';
  378.                     l++;
  379.                     dir[l] = 0;
  380.                 }
  381.             }
  382.             rtFreeRequest(filereq);
  383.             return(TRUE);
  384.         }
  385.         rtFreeRequest(filereq);
  386.     }
  387.     return(FALSE);
  388. }
  389.  
  390.  
  391. struct Scroll
  392. {
  393.     struct Node    nnode;
  394.     long        len;
  395. };
  396.  
  397. void AddBuf(unsigned char *str, long size)
  398. {
  399.     register long i = 0, n;
  400.     struct Scroll *node, *nextnode;
  401.     char numb[32];
  402.  
  403.     while(i < size)
  404.     {
  405.         switch(str[i])
  406.         {
  407.             case 10:
  408. add:
  409.                 scrollbuf[jj] = 0;
  410.                 jj += 2;
  411.                 node = AllocMem(sizeof(struct Scroll) + jj, MEMF_PUBLIC|MEMF_CLEAR);
  412.                 if(node)
  413.                 {
  414.                     node->nnode.ln_Name = (char *) (long)node + sizeof(struct Scroll);
  415.                     node->len = jj;
  416.                     CopyMem(scrollbuf, node->nnode.ln_Name, jj - 2);
  417.                     AddTail(slist, node);
  418.                     lines++;
  419.                 }
  420.                 if(lines > prefs.sb_lines)
  421.                 {
  422.                     lines--;
  423.                     node = (struct Scroll *)slist->lh_Head;
  424.                     nextnode = (struct Scroll *)node -> nnode.ln_Succ;
  425.                     if(nextnode)
  426.                     {
  427.                         Remove(node);
  428.                         FreeMem(node, sizeof(struct Scroll)+node->len);
  429.                     }
  430.                 } else {
  431.                     if(sbwin)
  432.                     {
  433.                         SetGadgetAttrs((struct Gadget *)Scroller, sbwin, NULL,
  434.                             PGA_Total,    lines,
  435.                         TAG_DONE);
  436.                     }
  437.                 }
  438.                 jj = 0;
  439.                 break;
  440.             case 7:
  441.             case 9:
  442.             case ' ':
  443.             case 13:
  444.                 break;
  445.             case 27:
  446.                 i++;
  447.             case 155:
  448.                 n = 0;
  449.                 i++;
  450.                 while(i < size && str[i]>='0' && str[i]<=';')
  451.                 {
  452.                     numb[n] = str[i];
  453.                     i++;
  454.                     n++;
  455.                     if(n > 30) n = 0;
  456.                 }
  457.                 switch(str[i])
  458.                 {
  459.                     case ' ':
  460.                         i++;
  461.                         break;
  462.                     case 'C':
  463.                         numb[n] = 0;
  464.                         for(n=0; n<atoi(numb); n++)
  465.                         {
  466.                             if(jj > 400) goto add;
  467.                             scrollbuf[jj] = ' ';
  468.                             jj++;
  469.                         }
  470.                         break;
  471.                     case 'H':
  472.                     case 'B':
  473.                         goto add;
  474.                 }
  475.                 break;
  476.             default:
  477.                 if(jj > 400) goto add;
  478.                 scrollbuf[jj] = str[i];
  479.                 jj++;
  480.                 break;
  481.         }
  482.         i++;
  483.     }
  484. }
  485.  
  486. void Receive(void)
  487. {
  488.     register long length;
  489.  
  490.     if(passall)
  491.     {
  492.         if((length = recv(sok, buf, sizeof buf, 0)) < 1)
  493.             DisConnect(TRUE, FALSE);
  494.         else {
  495.             char upload = FALSE;
  496.             char download = FALSE;
  497.             static char zm;
  498.             UWORD i = 0, j = 0, temp;
  499.             unsigned char *outbuf = AllocMem(length+256, MEMF_PUBLIC);
  500.             if(!outbuf) return;
  501.  
  502.             /*fh = Open("ram:in.txt", MODE_READWRITE);
  503.             if(fh)
  504.             {
  505.                 Seek(fh, 0, OFFSET_END);
  506.                 Write(fh, buf, length);
  507.                 Close(fh);
  508.             }*/
  509.  
  510.             if(((prefs.flags&5) == 0)  &&  !icon) // if bits 0 and 2 are clear
  511.             {
  512.                 SetAPen(&scr->RastPort, 10);
  513.                 RectFill(&scr->RastPort, scr->Width-70, 3, scr->Width-62, prefs.fontsize-2);
  514.             }
  515.  
  516.             while(i < length)
  517.             {
  518.                 switch(buf[i])
  519.                 {
  520.                 case 0:
  521.                 case 14:
  522.                 case 128:
  523.                     break;
  524.                 case 10:
  525.                     if(!(prefs.flags&(1<<1))) goto norm;
  526.                     outbuf[j] = 13;
  527.                     j++;
  528.                     outbuf[j] = 10;
  529.                     j++;
  530.                     break;
  531.                 case 13:
  532.                     if(!(prefs.flags&(1<<1))) goto norm; // !CRLF Correction
  533.                     break;
  534.                 case 27:
  535.                     if(!(prefs.flags&(1<<6))) goto norm; // !Strip Color
  536.                     temp = i;
  537.                     i += 2;
  538.                     while(i < length && buf[i]>='0' && buf[i]<=';') i++;
  539.                     if(buf[i] != 'm')
  540.                     {
  541.                         i = temp;
  542.                         goto norm;
  543.                     }
  544.                     break;
  545.                 case 255:
  546.                     i += 2;
  547.                     break;
  548.                 case '1':
  549.                     if(zm == 5) upload = TRUE;
  550.                     goto pnorm;
  551.                 case '0':
  552.                     if(zm == 5) download = TRUE;
  553.                     if(zm == 4) zm = 5; else zm = 0;
  554.                     goto norm;
  555.                 case 'B':
  556.                     if(zm == 3) zm = 4; else zm = 0;
  557.                     goto norm;
  558.                 case '\030':
  559.                     if(zm == 2) zm = 3; else zm = 0;
  560.                     goto norm;
  561.                 case '*':
  562.                     if(zm < 3) zm++; else zm = 0;
  563.                     goto norm;
  564.                 default:
  565. pnorm:                    zm = 0;
  566. norm:                    outbuf[j] = buf[i];
  567.                     j++;
  568.                 }
  569.                 i++;
  570.             }
  571.  
  572.             ConWrite(outbuf, j);
  573.  
  574.             if(!(prefs.flags&(1<<5))) AddBuf(outbuf, j);
  575.  
  576.             /*if(debug)
  577.             {
  578.                 fh = Open("ram:out.txt", MODE_READWRITE);
  579.                 if(fh)
  580.                 {
  581.                     Seek(fh, 0, OFFSET_END);
  582.                     Write(fh, outbuf, j);
  583.                     Close(fh);
  584.                 }
  585.             }*/
  586.  
  587.             if(((prefs.flags&5) == 0)  &&  !icon) EraseRect(&scr->RastPort, scr->Width-72, 2, scr->Width-60, prefs.fontsize-1);
  588.  
  589.             FreeMem(outbuf, length+256);
  590.  
  591.             if(download) Download(prefs.xferlibrary);
  592.             if(upload) Upload(prefs.xferlibrary);
  593.  
  594.             bytes += length;
  595.         }
  596.     } else {
  597.  
  598.         if((recv(sok, buf, 1, 0)) < 1)
  599.         {
  600.             DisConnect(TRUE, FALSE);
  601.             return;
  602.         }
  603.  
  604.         if(buf[0] == 255  &&  !(prefs.flags&(1<<13))) // NOT RAW
  605.         {
  606.             if((recv(sok, &buf[1], 2, 0)) < 1)
  607.             {
  608.                 DisConnect(TRUE, FALSE);
  609.                 return;
  610.             }
  611.             bytes += 2;
  612.  
  613.             if(prefs.flags&(1<<7)) // Simple Negotiation
  614.             {
  615.                 if(buf[1] == 253)
  616.                 {
  617.                     if(!buf[2])
  618.                         passall = TRUE;
  619.                     else {
  620.                         buf[1] = 252;
  621.                         TCPSend(buf, 3);
  622.                     }
  623.                 }
  624.             } else {
  625.                 switch(buf[1])
  626.                 {
  627.                     case 250: //SubNeg
  628.                         recv(sok, &buf[8], 3, 0);
  629.                         bytes += 3;
  630.                         if(buf[2] == 24)
  631.                         {
  632.                             //recv(sok, buf, 3, 0);
  633.                             TCPSend("\377\372\030\000", 4);
  634.                             TCPSend(prefs.displayidstr, strlen(prefs.displayidstr));
  635.                             TCPSend("\377\360", 2);
  636.                         }
  637.                         break;
  638.                     case 253: //DO
  639.                         if(!buf[2])
  640.                             passall = TRUE;
  641.                         else {
  642.                             if(buf[2] != 24) // !TERMTYPE
  643.                                 buf[1] = 252; //WON'T
  644.                             else
  645.                                 buf[1] = 251; //WILL
  646.                             TCPSend(buf, 3);
  647.                         }
  648.                         break;
  649.                     case 251: //WILL
  650.                         /*switch(buf[2])
  651.                         {
  652.                         case 0:
  653.                         case 1:
  654.                         case 3:
  655.                             break;
  656.                         default:
  657.                             buf[1] = 254;    // DONT
  658.                             TCPSend(buf, 3);
  659.                         }*/
  660.                         if(buf[2] > 1)
  661.                         {
  662.                             buf[1] = 254; //DON'T
  663.                             TCPSend(buf, 3);
  664.                         }
  665.                         break;
  666.                 }
  667.             }
  668.         } else {
  669.             bytes++;
  670.             if(buf[0]) ConWrite(buf, 1);
  671.             if(bytes > 128) passall = TRUE;
  672.         }
  673.     }
  674. }
  675.  
  676. void SendMisc(char *str, long len)
  677. {
  678.     if(len == -1) len = strlen(str);
  679.  
  680.     if(connected)
  681.         TCPSend(str, len);
  682.     else
  683.         ConWrite(str, len);
  684. }
  685.  
  686. void SendMacro(char *str)
  687. {
  688.     register UWORD t, i = 0, j = 0, len = strlen(str);
  689.  
  690.     while(i < len)
  691.     {
  692. cont:
  693.         switch(str[i])
  694.         {
  695.             case '\\':
  696.                 i++;
  697.                 switch(str[i])
  698.                 {
  699.                     case 'n':
  700.                         buf[j] = '\n';
  701.                         j++;
  702.                         break;
  703.                     case 'r':
  704.                         buf[j] = '\r';
  705.                         j++;
  706.                         break;
  707.                     case 'e':
  708.                         buf[j] = 27;
  709.                         j++;
  710.                         break;
  711.                     default:
  712.                         t = 0;
  713.                         while(i + t < len)
  714.                         {
  715.                             if(str[i+t] < '0' || str[i+t] > '9') break;
  716.                             t++;
  717.                             if(t == 3)
  718.                             {
  719.                                 UBYTE n = str[i+t];
  720.                                 str[i+t] = 0;
  721.                                 buf[j] = atoi((char *)&str[i]);
  722.                                 j++;
  723.                                 str[i+t] = n;
  724.                                 i += 3;
  725.                                 goto cont;
  726.                             }
  727.                         }
  728.                         i--;
  729.                         goto norm;
  730.                 }
  731.                 break;
  732.             default:
  733. norm:                buf[j] = str[i];
  734.                 j++;
  735.         }
  736.         i++;
  737.     }
  738.  
  739.     SendMisc(buf, j);
  740. }
  741.  
  742. void LEDs(void)
  743. {
  744.     if((prefs.flags&5) == 0  &&  !icon) // if bits 0 and 2 are clear
  745.     {
  746.         EraseRect(&scr->RastPort, scr->Width-72, 2, scr->Width-60, prefs.fontsize-1);
  747.         EraseRect(&scr->RastPort, scr->Width-86, 2, scr->Width-74, prefs.fontsize-1);
  748.         if(connected)
  749.         {
  750.             SetAPen(&scr->RastPort, 15);
  751.             RectFill(&scr->RastPort, scr->Width-84, 3, scr->Width-76, prefs.fontsize-2);
  752.         }
  753.     }
  754. }
  755.  
  756. /*void SpeedTest(void)
  757. {
  758.     long before;
  759.     register long spent;
  760.     register UWORD i;
  761.  
  762.     ConWrite("›0 p\233m\014", 7);
  763.  
  764.     before = mytime();
  765.  
  766.     for(i = 1; i < 201; i++) LocalFmt("Line %ld.\r\n", i);
  767.  
  768.     spent = mytime() - before;
  769.  
  770.     ConWrite("›1 p", 4);
  771.  
  772.     if(spent > 0)
  773.     {
  774.         //LocalFmt("›32mResult›33m: ›36m%ld ›mlines/second.\r\n", 200 / spent);
  775.         before = 200 / spent;
  776.         rtEZRequestA("Result: %ld lines per second.", "OK", NULL, (APTR)&before, (struct TagItem *)&tags);
  777.     }
  778. }*/
  779.  
  780. void SpeedTest(void)
  781. {
  782.     ULONG before_s, before_m;
  783.     ULONG after_s, after_m;
  784.     ULONG before, after;
  785.     register UWORD i;
  786.  
  787.     ConWrite("›0 p\233m\014", 7);
  788.  
  789.     CurrentTime(&before_s, &before_m);
  790.  
  791.     for(i = 1; i < 201; i++) LocalFmt("Line %ld.\r\n", i);
  792.  
  793.     CurrentTime(&after_s, &after_m);
  794.  
  795.     ConWrite("›1 p", 4);
  796.  
  797.     before = (before_s * 1000000) + before_m;
  798.     after  = (after_s  * 1000000) + after_m;
  799.  
  800.     after -= before;
  801.  
  802.     if(after > 0)
  803.     {
  804.         register char *rating;
  805.         before = 200000000 / after;
  806.  
  807.         if(before < 20)
  808.             rating = "Poor";
  809.         else {
  810.             if(before < 30)
  811.                 rating = "Average";
  812.             else {
  813.                 if(before < 50)
  814.                     rating = "Good";
  815.                 else
  816.                     rating = "Excellent";
  817.             }
  818.         }
  819.  
  820.         mysprintf(buf,    "Result: %ld lines per second\n\n"
  821.                 "Rating: %s", before, rating);
  822.  
  823.         SimpleReq(buf);
  824.     }
  825. }
  826.  
  827. void ClearScrollBack(void)
  828. {
  829.     struct Scroll *worknode, *nextnode;
  830.  
  831.     worknode = (struct Scroll *)slist->lh_Head;
  832.     while(worknode)
  833.     {
  834.         nextnode = (struct Scroll *)worknode -> nnode.ln_Succ;
  835.         if(!nextnode) break;
  836.  
  837.         FreeMem(worknode, sizeof(struct Scroll)+worknode->len);
  838.         worknode = nextnode;
  839.     }
  840.     slist->lh_Tail = 0;
  841.     slist->lh_TailPred = (struct Node *)slist;
  842.     slist->lh_Head = (struct Node *)&slist->lh_Tail;
  843. }
  844.  
  845. void Finger(void)
  846. {
  847.     long oldflags;
  848.     char tbuf[64];
  849.     char *host;
  850.  
  851.     if(rtGetStringA(tbuf, 63, "Enter EMail Address:", 0, (struct TagItem *)&tags))
  852.     {
  853.         host = strchr(tbuf, '@');
  854.         if(host)
  855.         {
  856.             host[0] = 0;
  857.             *host++;
  858.             oldflags = prefs.flags;
  859.             prefs.flags = 1<<13;    // Raw Connection
  860.             if(Connect_To_Server(host, 79) == 0)
  861.             {
  862.                 mysprintf(buf, "/W %s\r\n", tbuf);
  863.                 send(sok, buf, strlen(buf), 0);
  864.                 OffMenu(win, FULLMENUNUM(3, -1, 0));
  865.                 finger = TRUE;
  866.             }
  867.             prefs.flags = oldflags;
  868.         }
  869.     }
  870. }
  871.  
  872. void main(int argc, char *argv[])
  873. {
  874.     ULONG iconsig, sigmask, winsig;
  875.     LONG i;
  876.     struct timeval timer;
  877.     fd_set rd;
  878.  
  879.     if(argc > 1)
  880.     {
  881.         if(argv[1][0]=='?' && argv[1][1]==0)
  882.         {
  883.             PutStr("DCTelnet <host> [<port>]\n");
  884.             return;
  885.         }
  886.  
  887.         strcpy(server, argv[1]);
  888.  
  889.         if(argc > 2) cport = atoi(argv[2]);
  890.  
  891.         /*if(argc > 3)
  892.         {
  893.             if(stricmp(argv[3], "debug")==0) debug = TRUE;
  894.         }*/
  895.     }
  896.  
  897.     if (!(ReqToolsBase = (struct ReqToolsBase *)OpenLibrary (REQTOOLSNAME, 0)))
  898.     {
  899.         PutStr("I need reqtools.library\n");
  900.         return;
  901.     }
  902.  
  903.     fh = Open(prefsfile, MODE_OLDFILE);
  904.     if(fh)
  905.     {
  906.         if(Read(fh, &prefs, sizeof(struct PrefsStruct)) < 252) // IF OLD CONFIG FILE
  907.         {
  908.             /*//prefs.win_left = 0;
  909.             prefs.win_top = 11;
  910.             prefs.win_width = 640;
  911.             prefs.win_height = 200;
  912.             //prefs.sb_left = 0;
  913.             prefs.sb_top = 12;
  914.             prefs.sb_width = 640;
  915.             prefs.sb_height = (prefs.DisplayHeight / 2) - 4;*/
  916.  
  917.             Close(fh);
  918.             goto fixprefs;
  919.         }
  920.         Close(fh);
  921.     } else {
  922.  
  923.         icon = TRUE;
  924.  
  925.         SimpleReq(    "This is the first time you've run DCTelnet."    "\n"
  926.                                         "\n"
  927.                 "You will now have to select a screen mode"    "\n"
  928.                 "for DCTelnet to open on. The recommended"    "\n"
  929.                 "mode is 640*256*16 for good ANSI emulation."    "\n"
  930.                                         "\n"
  931.                 "Once DCTelnet has started, you can make"    "\n"
  932.                 "the program open a window on the Workbench"    "\n"
  933.                 "screen, instead of opening its own screen."
  934.             );
  935.  
  936.         if(ChooseScreen(TRUE))
  937.         {
  938.             prefs.fontsize = 8;
  939.             strcpy(prefs.fontname, "topaz.font");
  940.             strcpy(prefs.xferlibrary, "xprzmodem.library");
  941.             strcpy(prefs.xferinit, "TC,OR,B32,FO,AN,DN,KY,SN,RN");
  942.             memcpy(&prefs.color[0], &color[0], 32);
  943.             //CopyMem(&color[0], &prefs.color[0], 32);
  944.             prefs.flags = 1<<10;
  945. fixprefs:        //prefs.win_left = 0;
  946.             prefs.win_top = 11;
  947.             prefs.win_width = 640;
  948.             prefs.win_height = 200;
  949.             //prefs.sb_left = 0;
  950.             prefs.sb_top = 12;
  951.             prefs.sb_width = 640;
  952.             prefs.sb_height = (prefs.DisplayHeight / 2) - 4;
  953.             SavePrefs();
  954.         } else
  955.             goto xit;
  956.     }
  957.  
  958.     if(prefs.sb_lines == 0) prefs.sb_lines = 300;
  959.     if(prefs.displayidstr[0] == 0) strcpy(prefs.displayidstr, "VT102");
  960.  
  961.     fh = Open(keysfile, MODE_OLDFILE);
  962.     if(fh)
  963.     {
  964.         Read(fh, keys, 1520);
  965.         Close(fh);
  966.     }
  967.  
  968.     slist = AllocMem(sizeof(struct List), MEMF_CLEAR|MEMF_PUBLIC);
  969.     if(!slist) goto xit;
  970.     slist->lh_TailPred = (struct Node *)slist;
  971.     slist->lh_Head = (struct Node *)&slist->lh_Tail;
  972.  
  973.     GfxBase = ReqToolsBase -> GfxBase;
  974.     GadToolsBase = ReqToolsBase -> GadToolsBase;
  975.     IntuitionBase = ReqToolsBase -> IntuitionBase;
  976.     UtilityBase = ReqToolsBase -> UtilityBase;
  977.  
  978.     WorkbenchBase = OpenLibrary("workbench.library", 0);
  979.     DiskfontBase = OpenLibrary("diskfont.library", 0);
  980.     KeymapBase = OpenLibrary("keymap.library", 0);
  981.     IconBase = OpenLibrary("icon.library", 0);
  982.     SocketBase = OpenLibrary("bsdsocket.library", 0);
  983.  
  984.     reopenscreen = TRUE;
  985. restart:
  986.     if(OpenDisplay(reopenscreen))
  987.     {
  988.         if(!restartflag && server[0] != 0 && !connected) Connect_To_Server(server, cport);
  989.         restartflag = FALSE;
  990.         reopenscreen = FALSE;
  991.  
  992.         timer.tv_sec = 30;
  993.         timer.tv_usec = 0;
  994.  
  995.  
  996. /* ------ main loop ------ */
  997.  
  998. startloop:
  999.     while(!done)
  1000.     {
  1001.  
  1002.         if(doicon)
  1003.         {
  1004.             CloseDisplay(TRUE);
  1005.             OpenIcon();
  1006.             doicon = FALSE;
  1007.         }
  1008.  
  1009.         if(unicon)
  1010.         {
  1011.             CloseIcon();
  1012.             OpenDisplay(TRUE);
  1013.             unicon = FALSE;
  1014.         }
  1015.  
  1016.         if(icon) // ICONIFIED
  1017.         {
  1018.             if(iconport) iconsig = 1L<<iconport->mp_SigBit;
  1019.  
  1020.             if(connected)
  1021.             {
  1022.                 FD_ZERO(&rd);
  1023.                 FD_SET(sok, &rd);
  1024.                 sigmask = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | iconsig;
  1025.  
  1026.                 i = WaitSelect(sok + 1, &rd, 0, 0, &timer, &sigmask);
  1027.  
  1028.             } else {
  1029.                 i = 0;
  1030.                 sigmask = Wait( SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | iconsig );
  1031.             }
  1032.  
  1033.              if(sigmask&SIGBREAKF_CTRL_F) unicon = TRUE;
  1034.  
  1035.             if(sigmask&SIGBREAKF_CTRL_C) done = TRUE;
  1036.  
  1037.             if(sigmask&iconsig)
  1038.             {
  1039.                 register struct AppMessage *appmsg;
  1040.                 while(appmsg = (struct AppMessage *)GetMsg(iconport))
  1041.                 {
  1042.                     if(appmsg->am_NumArgs==0 && appmsg->am_ArgList==0) unicon = TRUE;
  1043.                     ReplyMsg(appmsg);
  1044.                 }
  1045.             }
  1046.  
  1047.             if(i != 0) Receive();
  1048.  
  1049.         } else {
  1050.  
  1051.             winsig = 1L << win->UserPort->mp_SigBit;
  1052.             if(connected)
  1053.             {
  1054.                 FD_ZERO(&rd);
  1055.                 FD_SET(sok, &rd);
  1056.  
  1057.                 sigmask = winsig;
  1058.  
  1059.                 if(sbwin) sigmask |= 1L << sbwin->UserPort->mp_SigBit;
  1060.                 if(pwin) sigmask |= 1L << pwin->UserPort->mp_SigBit;
  1061.                 if(twin) sigmask |= 1L << twin->UserPort->mp_SigBit;
  1062.  
  1063.                 i = WaitSelect(sok + 1, &rd, 0, 0, &timer, &sigmask);
  1064.  
  1065.                 GetWindowMsg(win);
  1066.  
  1067.                 if(sbwin) GetWindowMsg(sbwin);
  1068.                 if(pwin) GetWindowMsg(pwin);
  1069.                 if(twin) GetWindowMsg(twin);
  1070.  
  1071.                 if(i != 0) Receive();
  1072.  
  1073.             } else {
  1074.                 ULONG sig;
  1075.  
  1076.                 if(sbwin)  sig = 1L << sbwin->UserPort->mp_SigBit; else sig = 0;
  1077.                 if(pwin) sig |= 1L << pwin->UserPort->mp_SigBit;
  1078.                 if(twin) sig |= 1L << twin->UserPort->mp_SigBit;
  1079.  
  1080.                 sigmask = Wait( sig | winsig | SIGBREAKF_CTRL_C );
  1081.  
  1082.                 if(sbwin)
  1083.                 {
  1084.                     if(sigmask&(1L << sbwin->UserPort->mp_SigBit)) GetWindowMsg(sbwin);
  1085.                 }
  1086.                 if(pwin)
  1087.                 {
  1088.                     if(sigmask&(1L << pwin->UserPort->mp_SigBit)) GetWindowMsg(pwin);
  1089.                 }
  1090.                 if(twin)
  1091.                 {
  1092.                     if(sigmask&(1L << twin->UserPort->mp_SigBit)) GetWindowMsg(twin);
  1093.                 }
  1094.  
  1095.                 if(sigmask&winsig) GetWindowMsg(win);
  1096.                 if(sigmask&SIGBREAKF_CTRL_C) done = TRUE;
  1097.             }
  1098.             if(restartflag)
  1099.             {
  1100.                 CloseDisplay(reopenscreen);
  1101.                 goto restart;
  1102.             }
  1103.  
  1104.         }
  1105.  
  1106.     }
  1107.  
  1108. /* -- end of main loop -- */
  1109.  
  1110.         CloseDisplay(TRUE);
  1111.         SavePrefs();
  1112.  
  1113.         prefs.flags = 1;
  1114.         DisConnect(FALSE, TRUE);
  1115.     }
  1116.  
  1117.     CloseLibrary(WorkbenchBase);
  1118.     CloseLibrary(IconBase);
  1119.     CloseLibrary(DiskfontBase);
  1120.     CloseLibrary(KeymapBase);
  1121.     CloseLibrary(SocketBase);
  1122.  
  1123.     ClearScrollBack();
  1124.     FreeMem(slist, sizeof(struct List));
  1125. xit:
  1126.     CloseLibrary((struct Library *)ReqToolsBase);
  1127. }
  1128.  
  1129. void LocalPrint(char *data)
  1130. {
  1131.     ConWrite(data, strlen(data));
  1132. }
  1133.  
  1134. void ConWrite(char *data, long len)
  1135. {
  1136.     if(!icon)
  1137.     {
  1138.         if(drivertype)
  1139.             XEmulatorWrite(&xemio, data, len);
  1140.         else {
  1141.             writeio.io_Data = data;
  1142.             writeio.io_Length = len;
  1143.             writeio.io_Command = CMD_WRITE;
  1144.             DoIO((struct IORequest *)&writeio);
  1145.         }
  1146.     }
  1147. }
  1148.  
  1149. void SaveScrollBack(char *fname)
  1150. {
  1151.     struct Scroll *worknode, *nextnode;
  1152.     fh = Lock(fname, SHARED_LOCK);
  1153.     if(fh)
  1154.     {
  1155.         UnLock(fh);
  1156.         if(!rtEZRequestA("File Already Exists.","OverWrite|Cancel", NULL, NULL, (struct TagItem *)&tags))
  1157.             return;
  1158.     }
  1159.     fh = Open(fname, MODE_NEWFILE);
  1160.     if(fh)
  1161.     {
  1162.         worknode = (struct Scroll *)slist->lh_Head;
  1163.         while(worknode)
  1164.         {
  1165.             nextnode = (struct Scroll *)worknode -> nnode.ln_Succ;
  1166.             if(!nextnode) break;
  1167.  
  1168.             Write(fh, (char *) (long)worknode + sizeof(struct Scroll), worknode->len-2);
  1169.             Write(fh, "\n", 1);
  1170.             worknode = nextnode;
  1171.         }
  1172.         Close(fh);
  1173.     }
  1174. }
  1175.  
  1176. void Connect(char thread)
  1177. {
  1178.     char tbuf[64];
  1179.     UWORD port = 0;
  1180.  
  1181.     if(!thread) strcpy(tbuf, server); else tbuf[0] = 0;
  1182.  
  1183.     if(rtGetStringA(tbuf, 63, "Enter host,port:", 0, (struct TagItem *)&tags))
  1184.     {
  1185.         if(tbuf[0] != 0)
  1186.         {
  1187.             register char *po;
  1188.             if(po = strchr(tbuf, ','))
  1189.             {
  1190.                 po[0] = 0;
  1191.                 port = atoi((char *)&po[1]);
  1192.             }
  1193.  
  1194.             if(!port) port = 23;
  1195.  
  1196.             if(thread)
  1197.             {
  1198.                 mysprintf(buf, "run DCTelnet %s %ld <>NIL:", tbuf, port);
  1199.                 Execute(buf, 0, 0);
  1200.             } else {
  1201.                 cport = port;
  1202.                 Connect_To_Server(tbuf, cport);
  1203.             }
  1204.         }
  1205.     }
  1206. }
  1207.  
  1208. void Information(void)
  1209. {
  1210.     if(connected)
  1211.     {
  1212.         register long spent = mytime() - contime;
  1213.  
  1214.         mysprintf(buf,    "     Host Name ... : %s\n"
  1215.                 "    IP Address ... : %s\n"
  1216.                 "      TCP Port ... : %ld\n\n"
  1217.                 "   Online Time ... : %02ld:%02ld:%02ld\n"
  1218.                 "    Bytes Sent ... : %ld\n"
  1219.                 "Bytes Received ... : %ld",
  1220.             HostAddr->h_name,
  1221.             Inet_NtoA(INetSocketAddr.sin_addr.s_addr),
  1222.             cport,
  1223.             spent/3600, (spent/60)%60, spent%60,
  1224.             sent,
  1225.             bytes);
  1226.  
  1227.         rtEZRequestTags(buf, "OK", NULL, NULL,
  1228.                 RT_Window,    win,
  1229.                 RT_ReqPos,    REQPOS_CENTERSCR,
  1230.                 TAG_DONE);
  1231.     } else
  1232.         SimpleReq("Not connected");
  1233. }
  1234.  
  1235. void CheckFlag(struct MenuItem *item, char bit)
  1236. {
  1237.     if(item->Flags & CHECKED)
  1238.         prefs.flags |= 1<<bit;
  1239.     else
  1240.         prefs.flags &= ~(1<<bit);
  1241. }
  1242.  
  1243. void OutKey(unsigned char key)
  1244. {
  1245.     if(prefs.flags&(1<<4)) // BS/DEL Swap
  1246.     {
  1247.         if(key == 8)
  1248.             key = 127;
  1249.         else {
  1250.             if(key == 127) key = 8;
  1251.         }
  1252.     }
  1253.     if(connected)
  1254.     {
  1255.         TCPSend((void *)&key, 1);
  1256.         if(key==(unsigned char)255) TCPSend((void *)&key, 1);
  1257.         if(!passflag)
  1258.         {
  1259.             TCPSend("\377\375\000\377\373\000", 6); // 8-bit data path
  1260.             passflag = TRUE;
  1261.         }
  1262.         if(prefs.flags&(1<<12)) goto cwrite;    // Local Echoback
  1263.     } else
  1264. cwrite:        ConWrite(&key, 1);
  1265. }
  1266.  
  1267.  
  1268. void GetWindowMsg(struct Window *wwin)
  1269. {
  1270.     struct MenuItem *item;
  1271.     struct IntuiMessage *message;
  1272.     struct rtFontRequester *fontreq;
  1273.     UWORD menuNumber, menuNum, itemNum;
  1274.     APTR reqinfo;
  1275.     struct Gadget *gad;
  1276.     ULONG class;
  1277.     UWORD code;
  1278.     UWORD qual;
  1279.     char fbuf[128];
  1280.     char close = FALSE;
  1281.     char resize = FALSE;
  1282.     char closetwin = FALSE;
  1283.     static char key_csi;
  1284.     static char key_macro;
  1285.  
  1286.     while (message = (struct IntuiMessage *)GetMsg(wwin->UserPort))
  1287.     {
  1288.         class = message->Class;
  1289.         code = message->Code;
  1290.         gad = (struct Gadget *)message->IAddress;
  1291.         qual = message->Qualifier;
  1292.         ReplyMsg(message);
  1293.  
  1294.         switch (class)
  1295.         {
  1296.         case IDCMP_GADGETUP:
  1297.             if(wwin == pwin)
  1298.             {
  1299.                 RemoveGList(wwin, &strGad, 1);
  1300.                 if(prefs.flags&(1<<11))
  1301.                     strcat(strBuffer, "\r\n");
  1302.                 else
  1303.                     strcat(strBuffer, "\r");
  1304.                 SendMacro(strBuffer);
  1305.                 strBuffer[0] = 0;
  1306.                 ((struct StringInfo *)(strGad.SpecialInfo))->BufferPos = 0;
  1307.                 ((struct StringInfo *)(strGad.SpecialInfo))->DispPos = 0;
  1308.                 AddGList(wwin, &strGad, ~0, 1, NULL);
  1309.                 RefreshGList(&strGad, wwin, NULL, 1);
  1310.                 ActivateGadget(&strGad, pwin, 0);
  1311.             }
  1312.  
  1313.             if(wwin == sbwin)
  1314.             {
  1315.                 GetAttr(PGA_Top, Scroller, (ULONG *)&lasttop);
  1316.                 RefreshListView(lasttop);
  1317.             }
  1318.  
  1319.             if(gad->GadgetID == 20) ScreenToBack(scr);
  1320.  
  1321.             if(wwin == twin)
  1322.             {
  1323.                 switch(gad->GadgetID)
  1324.                 {
  1325.                     case 0:
  1326.                         Connect(FALSE);
  1327.                         break;
  1328.                     case 1:
  1329.                         DisConnect(FALSE, FALSE);
  1330.                         break;
  1331.                     case 2:
  1332.                         WindowSub(AddressBook);
  1333.                         break;
  1334.                     case 3:
  1335.                         WindowSub(Information);
  1336.                         break;
  1337.                     case 4:
  1338.                     case 5:
  1339.                         if(connected)
  1340.                         {
  1341.                             if(gad->GadgetID == 4)
  1342.                                 Upload(prefs.xferlibrary);
  1343.                             else
  1344.                                 Download(prefs.xferlibrary);
  1345.                         } else
  1346.                             SimpleReq("You better connect first.");
  1347.                         break;
  1348.                     case 6:
  1349.                         //if(rtEZRequestA("Quit?", "Quit|Cancel", NULL, NULL, (struct TagItem *)&tags))
  1350.                             done = TRUE;
  1351.                         break;
  1352.                 }
  1353.             }
  1354.             break;
  1355.  
  1356.  
  1357.         case IDCMP_NEWSIZE:
  1358.             //LocalPrint("\017\233\164\233\165\233\166\233\167");
  1359.             if(wwin == sbwin) resize = TRUE;
  1360.             break;
  1361.  
  1362.  
  1363.         /*case IDCMP_REFRESHWINDOW:
  1364.             GT_RefreshWindow(wwin, NULL);
  1365.             break;*/
  1366.  
  1367.  
  1368.         case IDCMP_RAWKEY:
  1369.             if(wwin == sbwin)
  1370.             {
  1371.                 switch(code)
  1372.                 {
  1373.                 case 76:
  1374.                     goto up;
  1375.                 case 77:
  1376.                     goto down;
  1377.                 case 84:
  1378.                     buf[0] = 0;
  1379.                     strcpy(fbuf, "DCTelnet.Cap");
  1380.                     if(FileReq(buf, "#?", fbuf, "Save Scroll Back", TRUE, 0))
  1381.                     {
  1382.                         strcat(buf, fbuf);
  1383.                         SaveScrollBack(buf);
  1384.                     }
  1385.                     break;
  1386.                 case 82:
  1387.                     if(rtEZRequestA("Print Scrollback?", "Print|Cancel", NULL, NULL, (struct TagItem *)&tags))
  1388.                         SaveScrollBack("PRT:");
  1389.                     break;
  1390.                 case 80:
  1391.                     ClearScrollBack();
  1392.                     lines = 0;
  1393.                     lasttop = 0;
  1394.                     SetGadgetAttrs((struct Gadget *)Scroller, sbwin, NULL,
  1395.                         PGA_Total,    0,
  1396.                     TAG_DONE);
  1397.                     RefreshListView(0);
  1398.                     break;
  1399.                 }
  1400.             }
  1401.             if(wwin == win  ||  wwin == twin)
  1402.             {
  1403.                 struct InputEvent ie;
  1404.                 register ULONG i, length;
  1405.  
  1406.                 if(!(message->Code & IECODE_UP_PREFIX))
  1407.                 {
  1408.                     ie.ie_Class        = IECLASS_RAWKEY;
  1409.                     ie.ie_SubClass        = 0;
  1410.                     ie.ie_Code        = code;
  1411.                     ie.ie_Qualifier        = qual;
  1412.                     ie.ie_position.ie_addr    = gad;
  1413.  
  1414.                     length = MapRawKey(&ie, conbuf, 16, NULL);
  1415.  
  1416.                     for(i=0; i<length; i++)
  1417.                     {
  1418.                         switch(conbuf[i])
  1419.                         {
  1420.                         case 155:
  1421.                             key_csi = TRUE;
  1422.                             break;
  1423.                         /*case 'v':
  1424.                         case 'V':
  1425.                             if(qual&IEQUALIFIER_RCOMMAND)
  1426.                             {
  1427.                                 ConWrite("› v", 3);
  1428.                                 break;
  1429.                             }*/
  1430.                         default:
  1431.                             if(key_csi)
  1432.                             {
  1433.                                 key_csi = FALSE;
  1434.                                 if(conbuf[i] > 47 && conbuf[i] < 58)
  1435.                                 {
  1436.                                     key_macro = TRUE;
  1437.                                     SendMacro(&keys[(conbuf[i]-48)*152]);
  1438.                                 }
  1439.  
  1440.                                 switch(conbuf[i])
  1441.                                 {
  1442.                                 case 65:
  1443.                                     SendMisc("A", 3);
  1444.                                     break;
  1445.                                 case 66:
  1446.                                     SendMisc("B", 3);
  1447.                                     break;
  1448.                                 case 67:
  1449.                                     SendMisc("C", 3);
  1450.                                     break;
  1451.                                 case 68:
  1452.                                     SendMisc("D", 3);
  1453.                                     break;
  1454.                                 }
  1455.  
  1456.                             } else {
  1457.                                 if(key_macro)
  1458.                                     key_macro = FALSE;
  1459.                                 else
  1460.                                 {
  1461.                                     OutKey(conbuf[i]);
  1462.                                     if(conbuf[i] == '\r' && (prefs.flags&(1<<11))) OutKey('\n');
  1463.                                 }
  1464.                             }
  1465.                         }
  1466.                     }
  1467.                 }
  1468.             }
  1469.             break;
  1470.  
  1471.  
  1472.         case IDCMP_MENUPICK:
  1473.             LEDs();
  1474.             menuNumber = code;
  1475.             while (menuNumber != MENUNULL)
  1476.             {
  1477.                 item = ItemAddress(menuStrip, menuNumber);
  1478.                 menuNum = MENUNUM(menuNumber);
  1479.                 itemNum = ITEMNUM(menuNumber);
  1480.                 /*subNum  = SUBNUM(menuNumber);*/
  1481.                 switch(menuNum)
  1482.                 {
  1483.                 case 0:
  1484.                     switch(itemNum)
  1485.                     {
  1486.                     case 0:
  1487.                         rtEZRequestTags("        DCTelnet 1.5 By ZED^DC"        "\n"
  1488.                                                         "\n"
  1489.                                 "   First Compiled ... : May 17 1997"        "\n"
  1490.                                 "   Last Compiled .... : "__DATE__""        "\n"
  1491.                                 "   Compilers Used ... : SAS/C Compiler v6.58"    "\n"
  1492.                                 "                        SAS/C 680x0 Assembler"    "\n"
  1493.                                 "    Author Email .... : zed@mentasm.com"    "\n"
  1494.                                                         "\n"
  1495.                                 "        www.digital-corruption.net"        "\n"
  1496.                                                         "\n"
  1497.                                 "      Thanks to Ray Akey for his help."    "\n"
  1498.                                                         "\n"
  1499.                                 "  Stop by at #EliteCafe (irc.denet.co.jp)",
  1500.                                 "OK", NULL, NULL,
  1501.                                 RT_Window,    win,
  1502.                                 RT_ReqPos,    REQPOS_CENTERSCR,
  1503.                                 TAG_DONE);
  1504.                         break;
  1505.  
  1506.                     case 2:
  1507.                         if(wwin != sbwin)
  1508.                         {
  1509.                             CloseScrollBack();
  1510.                             OpenScrollBack(lasttop);
  1511.                         }
  1512.                         break;
  1513.                     case 3:
  1514.                         doicon = TRUE;
  1515.                         break;
  1516.  
  1517.                     case 4:
  1518.                         SpeedTest();
  1519.                         break;
  1520.                     case 5:
  1521.                         WindowSub(Finger);
  1522.                         break;
  1523.                     case 7:
  1524.                         done = TRUE;
  1525.                         break;
  1526.                     }
  1527.                     break;
  1528.                 case 1:
  1529.                     if(connected)
  1530.                     {
  1531.                         switch(itemNum)
  1532.                         {
  1533.                         case 0:
  1534.                             Upload(prefs.xferlibrary);
  1535.                             break;
  1536.                         case 2:
  1537.                             Download(prefs.xferlibrary);
  1538.                             break;
  1539.  
  1540.                         case 4:
  1541.                             fbuf[0] = 0;
  1542.                             strcpy(buf, prefs.uploadpath);
  1543.                             if(FileReq(buf, "#?", fbuf, "ASCII Send", TRUE, 0))
  1544.                             {
  1545.                                 register long r;
  1546.                                 strcat(buf, fbuf);
  1547.                                 fh = Open(buf, MODE_OLDFILE);
  1548.                                 if(fh)
  1549.                                 {
  1550.                                     while(r = Read(fh, buf, sizeof buf))
  1551.                                     {
  1552.                                         register long i;
  1553.                                         for(i=0; i<r; i++)
  1554.                                         {
  1555.                                             if(buf[i] == 10 && buf[i+1] != 13 && buf[i-1] != 13) buf[i] = 13;
  1556.                                         }
  1557.                                         TCPSend(buf, r);
  1558.                                     }
  1559.                                     Close(fh);
  1560.                                 }
  1561.                             }
  1562.                             break;
  1563.  
  1564.                         }
  1565.                     } else
  1566.                         SimpleReq("You better connect first.");
  1567.                     break;
  1568.                 case 2:
  1569.                     switch(itemNum)
  1570.                     {
  1571.                     case 0:
  1572.                         Connect(FALSE);
  1573.                         break;
  1574.  
  1575.                     case 1:
  1576.                         Connect(TRUE);
  1577.                         break;
  1578.  
  1579.                     case 2:
  1580.                         DisConnect(FALSE, FALSE);
  1581.                         break;
  1582.  
  1583.                     case 4:
  1584.                         WindowSub(AddressBook);
  1585.                         break;
  1586.  
  1587.                     case 6:
  1588.                         WindowSub(Information);
  1589.                         break;
  1590.  
  1591.                     }
  1592.                     break;
  1593.                 case 3:
  1594.                     switch(itemNum)
  1595.                     {
  1596.                     case 0:
  1597.                         CheckFlag(item, 3);
  1598.                         restartflag = TRUE;
  1599.                         reopenscreen = TRUE;
  1600.                         break;
  1601.                     case 1:
  1602.                         if(item->Flags & CHECKED)
  1603.                         {
  1604.                             prefs.flags |= 1<<2;
  1605.  
  1606.                             if(!(prefs.flags&1))
  1607.                             {
  1608.                                 SetAPen(&scr->RastPort, 1);
  1609.                                 RectFill(&scr->RastPort, scr->Width-86, 2, scr->Width-60, prefs.fontsize-1);
  1610.                             }
  1611.                         } else {
  1612.                             prefs.flags &= ~(1<<2);
  1613.                             LEDs();
  1614.                         }
  1615.                         break;
  1616.                     case 2:
  1617.                         CheckFlag(item, 0);
  1618.                         restartflag = TRUE;
  1619.                         reopenscreen = TRUE;
  1620.                         break;
  1621.                     case 3:
  1622.                         CheckFlag(item, 1);
  1623.                         break;
  1624.                     case 4:
  1625.                         CheckFlag(item, 4);
  1626.                         break;
  1627.                     case 5:
  1628.                         CheckFlag(item, 5);
  1629.                         break;
  1630.                     case 6:
  1631.                         CheckFlag(item, 6);
  1632.                         if(item->Flags & CHECKED) LocalPrint("›m");
  1633.                         break;
  1634.                     case 7:
  1635.                         CheckFlag(item, 7);
  1636.                         break;
  1637.                     case 8:
  1638.                         if(wb)
  1639.                             SimpleReq("Packet Window cannot work in Workbench mode.");
  1640.                         else
  1641.                             restartflag = TRUE;
  1642.  
  1643.                         CheckFlag(item, 8);
  1644.                         break;
  1645.  
  1646.                     case 9:
  1647.                         restartflag = TRUE;
  1648.                         CheckFlag(item, 9);
  1649.                         break;
  1650.  
  1651.                     case 10:
  1652.                         CheckFlag(item, 10);
  1653.                         if(wb)
  1654.                         {
  1655.                             if(item->Flags & CHECKED)
  1656.                                 OpenToolWindow(TRUE);
  1657.                             else
  1658.                                 CloseToolWindow();
  1659.                         } else
  1660.                             restartflag = TRUE;
  1661.                         break;
  1662.  
  1663.                     case 11:
  1664.                         CheckFlag(item, 11);
  1665.                         break;
  1666.  
  1667.                     case 12:
  1668.                         CheckFlag(item, 12);
  1669.                         break;
  1670.  
  1671.                     case 13:
  1672.                         CheckFlag(item, 13);
  1673.                         break;
  1674.                     case 14:
  1675.                         CheckFlag(item, 14);
  1676.                         if(!wb && !(prefs.flags&(1<<9))) restartflag = TRUE;
  1677.                         break;
  1678.                     }
  1679.                     break;
  1680.  
  1681.                 case 4:
  1682.                     switch(itemNum)
  1683.                     {
  1684.                     case 0:
  1685.                         if(ChooseScreen(FALSE))
  1686.                         {
  1687.                             restartflag = TRUE;
  1688.                             reopenscreen = TRUE;
  1689.                         }
  1690.                         break;
  1691.  
  1692.                     case 1:
  1693.                         if(fontreq = rtAllocRequestA (RT_FONTREQ, NULL))
  1694.                         {
  1695.                             rtChangeReqAttr(fontreq,
  1696.                                 RTFO_FontName,        prefs.fontname,
  1697.                                 RTFO_FontHeight,    prefs.fontsize,
  1698.                                 TAG_END);
  1699.  
  1700.                             if(rtFontRequest(fontreq, "Screen Font..",
  1701.                                 RT_Window,    win,
  1702.                                 RTFO_Flags,    FREQF_FIXEDWIDTH,
  1703.                                 TAG_DONE))
  1704.                             {
  1705.                                 strcpy(prefs.fontname, fontreq->Attr.ta_Name);
  1706.                                 prefs.fontsize = fontreq->Attr.ta_YSize;
  1707.                                 restartflag = TRUE;
  1708.                                 reopenscreen = TRUE;
  1709.                             }
  1710.                             rtFreeRequest(fontreq);
  1711.                         }
  1712.                         break;
  1713.                     case 2:
  1714.                         reqinfo = rtAllocRequestA(RT_REQINFO, NULL);
  1715.                         if(reqinfo)
  1716.                         {
  1717.                             if(rtPaletteRequestA("Screen Palette..", reqinfo, (struct TagItem *)&tags) != -1)
  1718.                             {
  1719.                                 UWORD i = 0;
  1720.  
  1721.                                 while(i < 16)
  1722.                                 {
  1723.                                     prefs.color[i] = GetRGB4(scr->ViewPort.ColorMap, i);
  1724.                                     i++;
  1725.                                 }
  1726.                             }
  1727.                             rtFreeRequest(reqinfo);
  1728.                         }
  1729.                         break;
  1730.  
  1731.                     case 3:
  1732.                         fbuf[0] = 0;
  1733.                         strcpy(buf, prefs.downloadpath);
  1734.                         if(FileReq(buf, "#?", fbuf, "Download Path..", TRUE, FREQF_NOFILES))
  1735.                         {
  1736.                             strcpy(prefs.downloadpath, buf);
  1737.                         }
  1738.                         break;
  1739.  
  1740.                     case 4:
  1741.                         FileReq("LIBS:", "xpr#?.library", prefs.xferlibrary, "Transfer Protocol..", FALSE, FREQF_PATGAD);
  1742.                         break;
  1743.  
  1744.                     case 5:
  1745.                         rtGetStringA(prefs.xferinit, 51, "Protocol Init..", 0, (struct TagItem *)&tags);
  1746.                         break;
  1747.  
  1748.                     case 6:
  1749.                         WindowSub(FunctionKeys);
  1750.                         break;
  1751.  
  1752.                     case 7:
  1753.                         if(FileReq("LIBS:", "xem#?.library", prefs.displaydriver, "XEM Library..", FALSE, FREQF_PATGAD))
  1754.                         {
  1755.                             if(prefs.flags&(1<<9)) restartflag = TRUE;
  1756.                         }
  1757.                         break;
  1758.  
  1759.                     case 8:
  1760.                         rtGetStringA(prefs.displayidstr, 31, "Telnet Display ID..", 0, (struct TagItem *)&tags);
  1761.                         break;
  1762.  
  1763.                     case 9:
  1764.                         rtGetLongA(&prefs.sb_lines, "ScrollBack Lines..", NULL, (struct TagItem *)&tags);
  1765.                         break;
  1766.  
  1767.                     case 10:
  1768.                         prefs.win_top = win->TopEdge;
  1769.                         prefs.win_left = win->LeftEdge;
  1770.                         prefs.win_height = win->Height;
  1771.                         prefs.win_width = win->Width;
  1772.  
  1773.                         if(sbwin)
  1774.                         {
  1775.                             prefs.sb_left = sbwin->LeftEdge;
  1776.                             prefs.sb_top = sbwin->TopEdge;
  1777.                             prefs.sb_width = sbwin->Width;
  1778.                             prefs.sb_height = sbwin->Height;
  1779.                         }
  1780.                         if(twin)
  1781.                         {
  1782.                             prefs.twin_left = twin->LeftEdge;
  1783.                             prefs.twin_top = twin->TopEdge;
  1784.                         }
  1785.  
  1786.                         break;
  1787.                     }
  1788.                     break;
  1789.                 case 5:
  1790.                     switch(itemNum)
  1791.                     {
  1792.                     case 0:
  1793.                         SendMisc(username, -1);
  1794.                         SendMisc("\r", 1);
  1795.                         break;
  1796.                     case 1:
  1797.                         SendMisc(password, -1);
  1798.                         SendMisc("\r", 1);
  1799.                         break;
  1800.                     }
  1801.                     break;
  1802.                 }
  1803.                 menuNumber = item->NextSelect;
  1804.             }
  1805.             break;
  1806.  
  1807.  
  1808.         case IDCMP_CLOSEWINDOW:
  1809.             if(wwin == win) done = TRUE;
  1810.             if(wwin == sbwin) close = TRUE;
  1811.             if(wwin == twin) closetwin = TRUE;
  1812.             break;
  1813.  
  1814.  
  1815.         case IDCMP_IDCMPUPDATE:
  1816.             switch((UWORD)GetTagData(GA_ID, 0, (struct TagItem *)gad))
  1817.             {
  1818.             case GAD_UP:
  1819. up:                if(lasttop > 0) lasttop--;
  1820.                 break;
  1821.  
  1822.             case GAD_DOWN:
  1823. down:                if(lasttop+((sbwin->Height - (prefs.fontsize + scr->WBorTop + 2)) / prefs.fontsize) < lines) lasttop++;
  1824.                 break;
  1825.             }
  1826.             SetGadgetAttrs((struct Gadget *)Scroller, sbwin, NULL,
  1827.                 PGA_Top,    lasttop,
  1828.             TAG_DONE);
  1829.  
  1830.             RefreshListView(lasttop);
  1831.  
  1832.         }
  1833.     }
  1834. xit:
  1835.  
  1836.     if(resize)
  1837.     {
  1838.         SetRast(sbwin->RPort, 0);
  1839.         RefreshWindowFrame(sbwin);
  1840.         RefreshListView(lasttop);
  1841.         SetGadgetAttrs((struct Gadget *)Scroller, sbwin, NULL,
  1842.             PGA_Visible,    (sbwin->Height - (prefs.fontsize + scr->WBorTop + 2)) / prefs.fontsize,
  1843.         TAG_END);
  1844.     }
  1845.     if(close) CloseScrollBack();
  1846.     if(closetwin)
  1847.     {
  1848.         CloseToolWindow();
  1849.         prefs.flags &= ~(1<<10);
  1850.     }
  1851. }
  1852.  
  1853. void __inline CheckError(void)
  1854. {
  1855.     register long en = Errno();
  1856.  
  1857.     switch(en)
  1858.     {
  1859.         case EINTR:
  1860.             LocalPrint("ERROR: Interrupted system call.\r\n"); break;
  1861.         case EHOSTUNREACH:
  1862.             LocalPrint("ERROR: No route to host.\r\n"); break;
  1863.         case ECONNREFUSED:
  1864.             LocalPrint("ERROR: Connection refused.\r\n"); break;
  1865.         case ETIMEDOUT:
  1866.             LocalPrint("ERROR: Connection timeout.\r\n"); break;
  1867.         default:
  1868.             LocalFmt("Connection failed. Error %ld.\r\n", en);
  1869.     }
  1870. }
  1871.  
  1872. #include <dos/dostags.h>
  1873.  
  1874. struct Task *parent, *child;
  1875.  
  1876. extern void __saveds __asm Connect_To_Server_Child(void);
  1877.  
  1878. UWORD abort_flag;
  1879. UWORD connect_msg_type;
  1880. char *connect_string;
  1881.  
  1882. UWORD Connect_To_ServerA(char *servername, UWORD port);
  1883.  
  1884. UWORD Connect_To_Server(char *servername, UWORD port)
  1885. {
  1886.     UWORD ret;
  1887.  
  1888.     parent = FindTask(0);
  1889.  
  1890.     child = (struct Task *)CreateNewProcTags(NP_Entry, Connect_To_Server_Child, TAG_DONE);
  1891.  
  1892.     ret = Connect_To_ServerA(servername, port);
  1893.     Signal(child, SIGBREAKF_CTRL_C);
  1894.  
  1895.     Wait(SIGBREAKF_CTRL_E);
  1896.  
  1897.     while((SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C))
  1898.     {
  1899.     }
  1900.  
  1901.     return(ret);
  1902. }
  1903.  
  1904. void c_msg(char *msg, UWORD type)
  1905. {
  1906.     connect_string = msg;
  1907.     connect_msg_type = type;
  1908.     Signal(child, SIGBREAKF_CTRL_E);
  1909.     Wait(SIGBREAKF_CTRL_E);
  1910. }
  1911.  
  1912. UWORD Connect_To_ServerA(char *servername, UWORD port)
  1913. {
  1914.     if(!SocketBase) SocketBase = OpenLibrary("bsdsocket.library", 0);
  1915.  
  1916.     if(!SocketBase)
  1917.     {
  1918.         SimpleReq("You must start AmiTCP/Miami first.");
  1919.         return(255);
  1920.     }
  1921.  
  1922.     if((prefs.flags&5) == 0) // if bits 0 and 2 are clear
  1923.     {
  1924.         SetAPen(&scr->RastPort, 11);
  1925.         RectFill(&scr->RastPort, scr->Width-84, 3, scr->Width-76, prefs.fontsize-2);
  1926.     }
  1927.  
  1928.     DisConnect(FALSE, FALSE);
  1929.  
  1930.     c_msg("Looking up...", 4);
  1931.     c_msg(servername, 0);
  1932.  
  1933.     LocalFmt("\r\nLooking up ›32m%s›m...\r\n", servername);
  1934.  
  1935.     strcpy(server, servername);
  1936.  
  1937.     abort_flag = 0;
  1938.     HostAddr = gethostbyname(server);
  1939.     if(!HostAddr)
  1940.     {
  1941.         if(abort_flag)
  1942.             LocalPrint("Host lookup aborted.\r\n");
  1943.         else
  1944.             LocalPrint("Unknown host. Maybe you misspelt it?\r\n");
  1945.         LEDs();
  1946.         return(1);
  1947.     }
  1948.  
  1949.     INetSocketAddr.sin_len = sizeof(INetSocketAddr);
  1950.     INetSocketAddr.sin_port = port;
  1951.     INetSocketAddr.sin_family = AF_INET;
  1952.     INetSocketAddr.sin_addr.s_addr = 0;
  1953.  
  1954.     memcpy(&INetSocketAddr.sin_addr, HostAddr->h_addr, HostAddr->h_length);
  1955.     //CopyMem(HostAddr->h_addr, &INetSocketAddr.sin_addr, HostAddr->h_length);
  1956.  
  1957.     c_msg(Inet_NtoA(INetSocketAddr.sin_addr.s_addr), 1);
  1958.     c_msg(HostAddr->h_name, 2);
  1959.  
  1960.     LocalFmt("Connecting to ›32m%s›m (›36m%s›m) port ›35m%ld›m...\r\n",
  1961.         HostAddr->h_name,
  1962.         Inet_NtoA(INetSocketAddr.sin_addr.s_addr),
  1963.         port);
  1964.  
  1965.     sok = socket(HostAddr->h_addrtype, SOCK_STREAM, 0);
  1966.     if(sok == -1)
  1967.     {
  1968.         LocalPrint("Cannot Open Socket.\r\n");
  1969.         LEDs();
  1970.         return(2);
  1971.     }
  1972.  
  1973.     c_msg("Connecting...", 4);
  1974.  
  1975.     if(connect(sok, (struct sockaddr const *)&INetSocketAddr, sizeof(INetSocketAddr)) == -1)
  1976.     {
  1977.         CheckError();
  1978.         shutdown(sok, 2);
  1979.         CloseSocket(sok);
  1980.         LEDs();
  1981.         return(3);
  1982.     }
  1983.  
  1984.     LocalPrint("Connected.\r\n");
  1985.  
  1986.     if(!(prefs.flags&(1<<13)))
  1987.         TCPSend("\377\375\003", 3);
  1988.     else {
  1989.         passall = TRUE;
  1990.         passflag = TRUE;
  1991.     }
  1992.  
  1993.     if(wb) WindowToFront(win); else ScreenToFront(scr);
  1994.  
  1995.     contime = mytime();
  1996.  
  1997.     connected = TRUE;
  1998.  
  1999.     LEDs();
  2000.  
  2001.     return(0);
  2002. }
  2003.  
  2004. char OpenDisplay(char doscreen)
  2005. {
  2006.     long i;
  2007.  
  2008.     if(!doscreen) goto jump1;
  2009.  
  2010.     if(prefs.flags&(1<<3)) wb = TRUE; else wb = FALSE;
  2011.  
  2012.     fontattr.ta_Name = prefs.fontname;
  2013.     fontattr.ta_YSize = prefs.fontsize;
  2014.     ansifont = OpenDiskFont(&fontattr);
  2015.     if(!ansifont)
  2016.     {
  2017.         fontattr.ta_Name = "topaz.font";
  2018.         fontattr.ta_YSize = 8;
  2019.         ansifont = OpenFont(&fontattr);
  2020.     }
  2021.  
  2022.     if(wb)
  2023.     {
  2024.         prefs.flags |= (1<<2);           // Disable Leds
  2025.         prefs.flags &= ~(1<<8);           // Not Packet Window
  2026.         scr = LockPubScreen(0L);
  2027.     } else {
  2028.         register UWORD *pens;
  2029.         static struct NewScreen nscr;
  2030.  
  2031.         if(prefs.DisplayDepth < 3) pens = &colorpens[12]; else pens = colorpens;
  2032.  
  2033.         memcpy(&nscr.Width, &prefs.DisplayWidth, 6);
  2034.         nscr.BlockPen = 1;
  2035.         nscr.Type = CUSTOMSCREEN;
  2036.         nscr.Font = &fontattr;
  2037.         nscr.DefaultTitle = "DCTelnet 1.5 © "__DATE__" By ZED^DC";
  2038.  
  2039.         scr = OpenScreenTags(&nscr,
  2040.             SA_DisplayID,    prefs.DisplayID,
  2041.                               SA_Pens,    (ULONG)pens,
  2042.             SA_ShowTitle,    !prefs.flags&1,
  2043.             SA_AutoScroll,    TRUE,
  2044.             SA_Interleaved,    TRUE,
  2045.             TAG_END);
  2046. /*
  2047.         scr = OpenScreenTags(NULL,
  2048.             SA_Title,    "DCTelnet 1.5 © "__DATE__" By ZED^DC",
  2049.             SA_Width,    prefs.DisplayWidth,
  2050.             SA_Height,    prefs.DisplayHeight,
  2051.             SA_DisplayID,    prefs.DisplayID,
  2052.                               SA_Depth,    prefs.DisplayDepth,
  2053.             SA_ShowTitle,    !prefs.flags&1,
  2054.             SA_Type,    CUSTOMSCREEN,
  2055.                               SA_Pens,    (ULONG)pens,
  2056.             SA_Font,    &fontattr,
  2057.             SA_AutoScroll,    TRUE,
  2058.             SA_Interleaved,    TRUE,
  2059.                               TAG_END);*/
  2060.     }
  2061.  
  2062.     if(scr)
  2063.     {
  2064.         WinTop = (scr->WBorTop)+(scr->Font->ta_YSize)+1;
  2065.         vi = GetVisualInfoA(scr, 0);
  2066.         DrawInfo = GetScreenDrawInfo(scr);
  2067. jump1:
  2068.         nwin.Screen = scr;
  2069.         nwin.Type = PUBLICSCREEN;
  2070.         nwin.DetailPen = 255;
  2071.         nwin.BlockPen = 255;
  2072.  
  2073.         if(wb)
  2074.         {
  2075.             static UWORD sizes[4] = { 200, 50, 1600, 1200 };
  2076.  
  2077.             mynewmenu[24].nm_Flags |= CHECKED;       // WB
  2078.             //mynewmenu[38].nm_Flags = NM_ITEMDISABLED;  // Jump Scroll
  2079.             mynewmenu[40].nm_Flags = NM_ITEMDISABLED;  // ScreenMode
  2080.             mynewmenu[42].nm_Flags = NM_ITEMDISABLED;  // ScreenPalette
  2081.  
  2082.             memcpy(&nwin, &prefs.win_left, 8);
  2083.             memcpy(&nwin.MinWidth, &sizes, 8);
  2084.             nwin.IDCMPFlags = IDCMP_RAWKEY | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK;
  2085.             //nwin.Flags = WFLG_GIMMEZEROZERO|WFLG_NEWLOOKMENUS|WFLG_SIMPLE_REFRESH|WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SIZEGADGET;
  2086.             nwin.Flags = WFLG_GIMMEZEROZERO|WFLG_NEWLOOKMENUS|WFLG_SMART_REFRESH|WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SIZEGADGET;
  2087.             nwin.Title = "DCTelnet 1.5 © "__DATE__" By ZED^DC";
  2088.             nwin.FirstGadget = 0;
  2089.  
  2090.             CheckDimensions(&nwin);
  2091.  
  2092.             win = OpenWindow(&nwin);
  2093.             UnlockPubScreen(0L, scr);
  2094.             if(prefs.flags&(1<<10)) OpenToolWindow(FALSE);
  2095.         } else {
  2096.             struct Gadget *backgad;
  2097.             UWORD top, height;
  2098.  
  2099.             mynewmenu[24].nm_Flags = HIGHCOMP|CHECKIT|MENUTOGGLE;    // WB
  2100.             //mynewmenu[38].nm_Flags = HIGHCOMP|CHECKIT|MENUTOGGLE;    // Jump Scroll
  2101.             mynewmenu[40].nm_Flags = 0;    // ScreenMode
  2102.             mynewmenu[42].nm_Flags = 0;    // ScreenPalette
  2103.  
  2104.             LoadRGB4(&scr->ViewPort, (UWORD *)&prefs.color, 16);
  2105.  
  2106.             if(prefs.flags&(1<<10)) OpenToolWindow(FALSE);
  2107.  
  2108.             if(prefs.flags&1) // HIDE TITLE
  2109.             {
  2110.                 top = 0;
  2111.                 height = scr->Height;
  2112.                 backgad = &window_back;
  2113.                 window_back.Width = 20;
  2114.                 window_back.Height = 9;
  2115.                 window_back.Activation = RELVERIFY;
  2116.                 window_back.GadgetType = BOOLGADGET;
  2117.                 window_back.LeftEdge = scr->Width - 20;
  2118.                 window_back.GadgetID = 20;
  2119.             } else {
  2120.                 top = prefs.fontsize + 3;
  2121.                 height = scr->Height - (prefs.fontsize + 3);
  2122.                 backgad = 0;
  2123.             }
  2124.  
  2125.             if(twin)    // Tool Window
  2126.             {
  2127.                 top = twin->TopEdge + twin->Height + 1;
  2128.                 height = scr->Height - top;
  2129.                 if(backgad)
  2130.                 {
  2131.                     AddGadget(twin, backgad, -1);
  2132.                     backgad = 0;
  2133.                 }
  2134.             }
  2135.  
  2136.             nwin.LeftEdge = 0;
  2137.             nwin.Title = 0;
  2138.             nwin.Width = scr->Width;
  2139.  
  2140.             if(prefs.flags&(1<<8))    // Packet
  2141.             {
  2142.                 height -= (prefs.fontsize + 2);
  2143.                 strInfo.Buffer = strBuffer;
  2144.                 strInfo.MaxChars = BUFSIZE;
  2145.                 strGad.TopEdge = 2;
  2146.                 strGad.Activation = GACT_RELVERIFY | GACT_STRINGLEFT;
  2147.                 strGad.GadgetType = GTYP_STRGADGET;
  2148.                 strGad.SpecialInfo = &strInfo;
  2149.                 strGad.Width = scr->Width;
  2150.                 strGad.Height = prefs.fontsize;
  2151.  
  2152.                 nwin.TopEdge = top+height;
  2153.                 nwin.Height = prefs.fontsize+2,
  2154.                 nwin.FirstGadget = &strGad;
  2155.                 nwin.IDCMPFlags =    IDCMP_MENUPICK |
  2156.                             IDCMP_GADGETUP;
  2157.                 nwin.Flags =    WFLG_NEWLOOKMENUS |
  2158.                         WFLG_BORDERLESS |
  2159.                         WFLG_BACKDROP;
  2160.  
  2161.                 pwin = OpenWindow(&nwin);
  2162.  
  2163.                 SetAPen(pwin->RPort, 1);
  2164.                 Draw(pwin->RPort, pwin->Width, 0);
  2165.             }
  2166.  
  2167.             nwin.TopEdge = top;
  2168.             nwin.Height = height;
  2169.             nwin.FirstGadget = backgad;
  2170.             nwin.IDCMPFlags =    IDCMP_GADGETUP |
  2171.                         IDCMP_RAWKEY |
  2172.                         IDCMP_CLOSEWINDOW |
  2173.                         IDCMP_MENUPICK;
  2174.             nwin.Flags =    WFLG_SMART_REFRESH |
  2175.                     WFLG_NEWLOOKMENUS |
  2176.                     WFLG_BORDERLESS |
  2177.                     WFLG_ACTIVATE |
  2178.                     WFLG_BACKDROP;
  2179.  
  2180.             win = OpenWindow(&nwin);
  2181.         }
  2182.  
  2183.         if(win)
  2184.         {
  2185.             if((prefs.flags&(1<<9)) && prefs.displaydriver[0])
  2186.             {
  2187.                 drivertype = 1;
  2188.                 mynewmenu[38].nm_Flags = NM_ITEMDISABLED;
  2189.             } else {
  2190.                 drivertype = 0;
  2191.                 mynewmenu[38].nm_Flags = HIGHCOMP|CHECKIT|MENUTOGGLE;
  2192.                 prefs.flags &= ~(1<<9);
  2193.             }
  2194.  
  2195.             if(prefs.flags&(1<<0))
  2196.                 mynewmenu[26].nm_Flags |= CHECKED;
  2197.             else
  2198.                 mynewmenu[26].nm_Flags = HIGHCOMP|CHECKIT|MENUTOGGLE;
  2199.  
  2200.             if(prefs.flags&(1<<1)) // CRLF
  2201.                 mynewmenu[27].nm_Flags |= CHECKED;
  2202.             else
  2203.                 mynewmenu[27].nm_Flags = HIGHCOMP|CHECKIT|MENUTOGGLE;
  2204.  
  2205.             if(prefs.flags&(1<<2))
  2206.                 mynewmenu[25].nm_Flags |= CHECKED;
  2207.             else
  2208.                 mynewmenu[25].nm_Flags = HIGHCOMP|CHECKIT|MENUTOGGLE;
  2209.  
  2210.             for(i=4; i<15; i++)
  2211.             {
  2212.                 if(prefs.flags&(1<<i))
  2213.                     mynewmenu[i+24].nm_Flags |= CHECKED;
  2214.                 else
  2215.                     mynewmenu[i+24].nm_Flags &= ~CHECKED;
  2216.                     //mynewmenu[i+24].nm_Flags = HIGHCOMP|CHECKIT|MENUTOGGLE;
  2217.             }
  2218.  
  2219.             tags[0] = RT_Window;
  2220.             tags[1] = (ULONG)win;
  2221.             tags[2] = RT_WaitPointer;
  2222.             tags[3] = TRUE;
  2223.  
  2224.             SetFont(win->RPort, ansifont);
  2225.  
  2226.             if(menuStrip = CreateMenusA(mynewmenu, 0))
  2227.             {
  2228.                 static ULONG ltags[] = { GTMN_NewLookMenus, TRUE, TAG_END };
  2229.  
  2230.                 register struct MenuItem *item = menuStrip->FirstItem->NextItem->NextItem->NextItem->NextItem->NextItem->NextItem->NextItem;
  2231.                 if(prefs.DisplayDepth > 1) ((struct IntuiText *)item->ItemFill)->FrontPen = 15;
  2232.                 //item->Flags |= HIGHBOX;
  2233.                 //item->Flags &= ~HIGHCOMP;
  2234.                 item->Flags = 150;
  2235.  
  2236.                 ltags[1] = wb;
  2237.                  LayoutMenusA(menuStrip, vi, (struct TagItem *)<ags);
  2238.  
  2239.                 SetMenuStrip(win, menuStrip);
  2240.  
  2241.                 if(pwin) ResetMenuStrip(pwin, menuStrip);
  2242.                 if(twin) ResetMenuStrip(twin, menuStrip);
  2243.  
  2244.                 if(drivertype) goto lib;
  2245. cantfind:
  2246.                 WriteConPort = CreateMsgPort();
  2247.                 if(WriteConPort)
  2248.                 {
  2249.                     char *dev;
  2250.                     UWORD unit;
  2251.  
  2252.                     writeio.io_Message.mn_ReplyPort = WriteConPort;
  2253.                     writeio.io_Data = win;
  2254.                     writeio.io_Length = sizeof(struct Window);
  2255.  
  2256.                     if(wb)
  2257.                     {
  2258.                         dev = "console.device";
  2259.                         unit = 3;
  2260.                     } else {
  2261.                         dev = "ibmcon.device";
  2262.                         if(prefs.flags&(1<<14))
  2263.                             unit = 2;
  2264.                         else
  2265.                             unit = 1;
  2266.                     }
  2267.  
  2268.                     i = OpenDevice(dev, unit, (struct IORequest *)&writeio, 0);
  2269.  
  2270.                     if(i == 0)
  2271.                     {
  2272. lib:
  2273.                         if(drivertype)
  2274.                         {
  2275.                             XEmulatorBase = OpenLibrary(prefs.displaydriver, 0);
  2276.                             if(!XEmulatorBase)
  2277.                             {
  2278.                                 drivertype = 0;
  2279.                                 SimpleReq("Failed to open XEM library.");
  2280.                                 goto cantfind;
  2281.                             }
  2282.                             xemio.xem_window    = win;
  2283.                             xemio.xem_font         = ansifont;
  2284.                             //xemio.xem_signal    = 0;
  2285.                             xemio.xem_screendepth    = scr->BitMap.Depth;
  2286.                             xemio.xem_swrite    = (long (* )(UBYTE * , LONG ))xpr_swrite;
  2287.                             xemio.xem_sread        = (long (* )(UBYTE * , LONG , LONG ))xpr_sread;
  2288.                             xemio.xem_sbreak    = (long (* )(void))xpr_gets;
  2289.                             xemio.xem_sstart    = (void (* )(void))xpr_gets;
  2290.                             xemio.xem_sstop        = (long (* )(void))xpr_gets;
  2291.                             xemio.xem_sflush    = (long (* )(void))xpr_sflush;
  2292.                             xemio.xem_toptions    = (unsigned long (* )(LONG , struct xem_option ** ))xpr_gets;
  2293.                             xemio.xem_tgets        = (long (* )(UBYTE * , UBYTE * , ULONG ))xpr_gets;
  2294.                             xemio.xem_tbeep        = (void (* )(ULONG , ULONG ))xpr_gets;
  2295.                             //xemio.xem_console    = 0;
  2296.                             //xemio.xem_process_macrokeys = 0;
  2297.  
  2298.                             XEmulatorSetup(&xemio);
  2299.                             XEmulatorOpenConsole(&xemio);
  2300.                             XEmulatorMacroKeyFilter(&xemio, NULL);
  2301.                         }
  2302.  
  2303.                         icon = FALSE;
  2304.  
  2305.                         LEDs();
  2306.  
  2307.                         if(!connected)
  2308.                         {
  2309.                             register UWORD flags;
  2310.                             register char cpu;
  2311.  
  2312.                             flags = SysBase->AttnFlags;
  2313.                             cpu = '0';
  2314.                             if(flags & AFF_68010) cpu = '1';
  2315.                             if(flags & AFF_68020) cpu = '2';
  2316.                             if(flags & AFF_68030) cpu = '3';
  2317.                             if(flags & AFF_68040) cpu = '4';
  2318.                             if(flags & AFF_68060) cpu = '6';
  2319.  
  2320.                             LocalFmt(
  2321.     "›0;1;36m\014\r\n\r\n"
  2322.     "Processor: ›37m680%lc0\r\n\r\n›36m"
  2323.     "Kickstart: ›37m%ld.%ld\r\n\r\n›36m"
  2324.     "TCP Stack: ›37m", cpu, ((struct Library *)SysBase)->lib_Version, SysBase->SoftVer);
  2325.  
  2326.                             if(SocketBase)
  2327.                             {
  2328.                                 register char *po;
  2329.                                 strcpy(buf, SocketBase->lib_IdString);
  2330.                                 po = strchr(buf, '\n');
  2331.                                 if(po) po[0] = 0;
  2332.                                 LocalPrint(buf);
  2333.                                 LocalPrint("›m\r\n\r\n");
  2334.                             } else
  2335.                                 LocalPrint("›31mNot active›m\r\n\r\n");
  2336.                         }
  2337.  
  2338.                         return(TRUE);
  2339.                     } else
  2340.                         SimpleReq("I need ibmcon.device");
  2341.                 }
  2342.             }
  2343.         }
  2344.     } else
  2345.         rtEZRequestA("Screen failed to open.", "OK", NULL, NULL, 0);
  2346.  
  2347.     CloseDisplay(TRUE);
  2348.  
  2349.     return(FALSE);
  2350. }
  2351.  
  2352. void CloseDisplay(char doscreen)
  2353. {
  2354.     if(drivertype)
  2355.     {
  2356.         if(win)
  2357.         {
  2358.             XEmulatorCloseConsole(&xemio);
  2359.             XEmulatorCleanup(&xemio);
  2360.             CloseLibrary(XEmulatorBase);
  2361.         }
  2362.     } else {
  2363.         if(writeio.io_Error == 0) CloseDevice((struct IORequest *)&writeio);
  2364.         if(WriteConPort) DeleteMsgPort(WriteConPort);
  2365.     }
  2366.  
  2367.     if(pwin)
  2368.     {
  2369.         ClearMenuStrip(pwin);
  2370.         CloseWindow(pwin);
  2371.         pwin = 0;
  2372.     }
  2373.  
  2374.     if(win)
  2375.     {
  2376.         ClearMenuStrip(win);
  2377.         CloseWindow(win);
  2378.     }
  2379.  
  2380.     CloseScrollBack();
  2381.     CloseToolWindow();
  2382.  
  2383.     if(menuStrip)    FreeMenus(menuStrip);
  2384.  
  2385.     if(doscreen)
  2386.     {
  2387.         if(vi)        FreeVisualInfo(vi);
  2388.         if(DrawInfo)    FreeScreenDrawInfo(scr, DrawInfo);
  2389.         if(!wb && scr)    CloseScreen(scr);
  2390.         if(ansifont)    CloseFont(ansifont);
  2391.     }
  2392.  
  2393.     icon = TRUE;
  2394. }
  2395.  
  2396. void OpenIcon(void)
  2397. {
  2398.     if(iconport = CreateMsgPort())
  2399.     {
  2400.         prefsfile[16] = 0;
  2401.         dobj = GetDiskObjectNew(prefsfile);
  2402.         prefsfile[16] = '.';
  2403.         if(dobj)
  2404.         {
  2405.             if(dcicon = AddAppIconA(0, 0, "DCTelnet", iconport, 0, dobj, 0)) return;
  2406.  
  2407.             FreeDiskObject(dobj);
  2408.         }
  2409.         DeleteMsgPort(iconport);
  2410.     }
  2411.     iconport = 0;
  2412. }
  2413.  
  2414. void CloseIcon(void)
  2415. {
  2416.     if(iconport)
  2417.     {
  2418.         RemoveAppIcon(dcicon);
  2419.         FreeDiskObject(dobj);
  2420.         DeleteMsgPort(iconport);
  2421.     }
  2422. }
  2423.